﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Main.Common
{
    public class MouseHook
    {
        public delegate void MouseMoveHandler(object sender, MouseEventArgs e);

        public delegate void MouseClickHandler(object sender, MouseEventArgs e);

        public delegate void MouseDownHandler(object sender, MouseEventArgs e);

        public delegate void MouseUpHandler(object sender, MouseEventArgs e);

        public const int WH_MOUSE_LL = 14;

        private Point point;

        private int hHook;

        private static int hMouseHook;

        public Win32Api2.HookProc hProc;

        private Point Point
        {
            get => point;
            set
            {
                if (this.point != value)
                {
                    this.point = value;
                    if (this.MouseMoveEvent != null)
                    {
                        MouseEventArgs e = new MouseEventArgs(MouseButtons.None, 0, this.point.X, this.point.Y, 0);
                        this.MouseMoveEvent(this, e);
                    }
                }
            }
        }

        public event MouseMoveHandler MouseMoveEvent;

        public event MouseClickHandler MouseClickEvent;

        public event MouseDownHandler MouseDownEvent;

        public event MouseUpHandler MouseUpEvent;

        public MouseHook()
        {
            Class2.Q91Y6x2zoRBWY();
            //base..ctor();
            this.Point = default(Point);
        }

        public int SetHook()
        {
            this.hProc = this.MouseHookProc;
            this.hHook = Win32Api2.SetWindowsHookEx(14, this.hProc, IntPtr.Zero, 0);
            return this.hHook;
        }

        public void UnHook()
        {
            Win32Api2.UnhookWindowsHookEx(this.hHook);
        }

        private int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
        {
            Win32Api2.MouseHookStruct mouseHookStruct = (Win32Api2.MouseHookStruct)Marshal.PtrToStructure(lParam, typeof(Win32Api2.MouseHookStruct));
            if (nCode < 0)
            {
                return Win32Api2.CallNextHookEx(this.hHook, nCode, wParam, lParam);
            }
            switch ((int)wParam)
            {
                case 513:
                    this.MouseDownEvent(this, new MouseEventArgs(MouseButtons.Left, 1, this.point.X, this.point.Y, 0));
                    break;
                case 514:
                    this.MouseUpEvent(this, new MouseEventArgs(MouseButtons.Left, 1, this.point.X, this.point.Y, 0));
                    break;
                case 516:
                    this.MouseDownEvent(this, new MouseEventArgs(MouseButtons.Right, 1, this.point.X, this.point.Y, 0));
                    break;
                case 517:
                    this.MouseUpEvent(this, new MouseEventArgs(MouseButtons.Right, 1, this.point.X, this.point.Y, 0));
                    break;
                case 519:
                    this.MouseDownEvent(this, new MouseEventArgs(MouseButtons.Middle, 1, this.point.X, this.point.Y, 0));
                    break;
                case 520:
                    this.MouseUpEvent(this, new MouseEventArgs(MouseButtons.Middle, 1, this.point.X, this.point.Y, 0));
                    break;
            }
            this.Point = new Point(mouseHookStruct.pt.x, mouseHookStruct.pt.y);
            return Win32Api2.CallNextHookEx(this.hHook, nCode, wParam, lParam);
        }

        static MouseHook()
        {
            Class2.Q91Y6x2zoRBWY();
            MouseHook.hMouseHook = 0;
        }
    }
}
